from django.shortcuts import render
from django.views import View
from django.conf import settings
from django import http
from django.contrib.auth import login
from django_redis import get_redis_connection
from django.db import DatabaseError

from apps.oauth.models import OAuthQQUser
from apps.oauth.utils import generate_access_token, check_access_token
from apps.users.models import User
from apps.carts.utils import merge_cart_cookie_to_redis
from QQLoginTool.QQtool import OAuthQQ
import json, re

# Create your views here.


class QQURLView(View):

    def get(self, request):
        next = request.GET.get('next', '/')

        # 创建OAuthQQ对象
        oauth = OAuthQQ(client_id=settings.QQ_CLIENT_ID,
                        client_secret=settings.QQ_CLIENT_SECRET,
                        redirect_uri=settings.QQ_REDIRECT_URI,
                        state=next)

        login_url = oauth.get_qq_url()

        return http.JsonResponse({"code": 0, "errmsg": "ok", "login_url": login_url})


class QQUserView(View):

    def get(self, request):
        """Oauth2.0认证"""
        code = request.GET.get('code')
        if not code:
            return http.JsonResponse({"code":400, "errmsg":"缺少code"})

        oauth = OAuthQQ(client_id=settings.QQ_CLIENT_ID,
                        client_secret=settings.QQ_CLIENT_SECRET,
                        redirect_uri=settings.QQ_REDIRECT_URI)
        try:
            access_token = oauth.get_access_token(code)
            openid = oauth.get_open_id(access_token)
        except Exception as e:
            return http.JsonResponse({"code":400, "errmsg":"网络错误"})

        try:
            oauth_qq = OAuthQQUser.objects.get(openid=openid)
        except OAuthQQUser.DoesNotExist:
            access_token = generate_access_token(openid)
            return http.JsonResponse({"code":300, "errmsg":"ok", "access_token": access_token})
        else:
            user = oauth_qq.user
            login(request, user)
            response = http.JsonResponse({"code": 0, "errmsg": "ok"})
            response.set_cookie('username', user.username, max_age=14 * 24 * 3600)
            merge_cart_cookie_to_redis(request, user, response)
            return response

    def post(self, request):
        json_dict = json.loads(request.body.decode())
        mobile = json_dict.get("mobile")
        password = json_dict.get("password")
        sms_code_client = json_dict.get("sms_code")
        access_token = json_dict.get("access_token")

        if not all([mobile, password, sms_code_client]):
            return http.JsonResponse({'code':400, 'errmsg': '缺少必传参数'})

        if not re.match(r'^1[3-9]\d{9}$', mobile):
            return http.JsonResponse({'code':400, 'errmsg': '请输入正确的手机号码'})

        if not re.match(r'^[0-9a-zA-Z-_]{8,20}$', password):
            return http.JsonResponse({'code':400, 'errmsg': '请输入8-20位的密码'})

        redis_conn = get_redis_connection('verify_code')
        sms_code_server = redis_conn.get('sms%s' % mobile).decode()

        if sms_code_server is None:
            return http.JsonResponse({'code':400, 'errmsg': '验证码失效'})

        if sms_code_client != sms_code_server:
            return http.JsonResponse({'code':400, 'errmsg': '请输入正确验证码'})

        openid = check_access_token(access_token)
        if not openid:
            return http.JsonResponse({'code':400, 'errmsg': '缺少openid'})

        try:
            user = User.objects.get(mobile=mobile)
        except User.DoesNotExist:
            user.objects.create_user(username=mobile, password=password, mobile=mobile)
        else:
            if not user.check_password(password):
                return http.JsonResponse({'code': 400, 'errmsg': '输入密码不正确'})

        try:
            OAuthQQUser.objects.create(openid=openid, user=user)
        except DatabaseError:
            return http.JsonResponse({'code':400, 'errmsg':'往数据库添加数据出错'})

        login(request, user)
        response = http.JsonResponse({'code': 0, 'errmsg':'ok'})
        response.set_cookie('username', user.username, max_age=14 * 24 * 3600)
        merge_cart_cookie_to_redis(request, user, response)
        return response













